#include "dominion.h"
#include "dominion_helpers.h"
#include "sput/sput.h"
#include <malloc.h>
#include <stdlib.h>
#include <time.h>

struct gameState *testState;

static void test_gain_card(void)
{
    int numPlayers;
    int supplyPos;
    int toFlag;
    int player;
    int res;
    int init_deck_count;
    int init_hand_count;
    int init_discard_count;
    int init_supply_count;

    int kc[10] = {adventurer, council_room, feast, gardens, mine, remodel,
                  smithy, village, baron, great_hall
                 };

    // iterate through all player counts
    for(numPlayers = 2; numPlayers <= MAX_PLAYERS; numPlayers++) {
        initializeGame(numPlayers, kc, rand(), testState);

        // iterate though all cards
        for(supplyPos = curse; supplyPos <= treasure_map; supplyPos++) {
            printf("init supplyPos: %d\n", supplyPos);

            //iterate over players
            for(player = 0; player < testState->numPlayers; player++) {

                // iterate over 'toFlag', which appears to represent a choice
                // of 1) the player's hand, 2) the player's deck, 3) the
                // discard pile.  The only values it takes in dominion.c are 0,
                // 1, and 2.  I might try passing a different value to see what
                // happens.
                for(toFlag = 0; toFlag <= 2; toFlag++) {
                    testState->supplyCount[supplyPos] = -1;
                    sput_fail_unless(gainCard(supplyPos, testState, toFlag, player) == -1, "abort when card count is -1");
                    testState->supplyCount[supplyPos] = 0;
                    sput_fail_unless(gainCard(supplyPos, testState, toFlag, player) == -1, "abort when card count is 0");


                    init_supply_count = testState->supplyCount[supplyPos] = 1;
                    init_deck_count = testState->deckCount[player];
                    init_hand_count = testState->handCount[player];
                    init_discard_count = testState->discardCount[player];

                    print_card(supplyPos);
                    printf("count before: %d\n", testState->supplyCount[supplyPos]);
                    res = gainCard(supplyPos, testState, toFlag, player);
                    printf("count after: %d\n", testState->supplyCount[supplyPos]);

                    if(toFlag == 1) {
                        sput_fail_unless(testState->deck[player][testState->deckCount[player] - 1] = supplyPos, "add card to deck");
                        sput_fail_unless(testState->deckCount[player] == init_deck_count + 1, "increment deck count");
                    } else if (toFlag == 2) {
                        sput_fail_unless(testState->hand[player][testState->handCount[player] - 1] = supplyPos, "add card to hand");
                        sput_fail_unless(testState->handCount[player] == init_hand_count + 1, "increment hand count");
                    } else {
                        sput_fail_unless(testState->discard[player][testState->discardCount[player] - 1] = supplyPos, "add card to discard");
                        sput_fail_unless(testState->discardCount[player] == init_discard_count + 1, "increment discard count");
                    }

                    sput_fail_unless(testState->supplyCount[supplyPos] == init_supply_count - 1, "decrement supply count");
                    sput_fail_unless(res == 0, "return 0 on successful card gain");
                }
            }
        }
    }
}

int main(int argc, char *argv[])
{
    // Seed random number generator
    srand(time(NULL));

    // Initialize game state
    testState = newGame();

    sput_start_testing();
    sput_enter_suite(__FILE__);

    sput_run_test(test_gain_card);
    sput_finish_testing();

    free(testState);

    return sput_get_return_value();
}
